Skip to content

drivers/serial: Refactor PL011 to be general-purpose#18837

Open
linguini1 wants to merge 1 commit into
apache:masterfrom
linguini1:pl011-uart
Open

drivers/serial: Refactor PL011 to be general-purpose#18837
linguini1 wants to merge 1 commit into
apache:masterfrom
linguini1:pl011-uart

Conversation

@linguini1
Copy link
Copy Markdown
Contributor

@linguini1 linguini1 commented May 2, 2026

Summary

This commit refactors the PL011 UART driver so that it can be re-used for any number of UART interfaces depending on the board/chip. This commit also hooks the UART interface configuration/selection for PL011 UART interfaces into the same Kconfig used for regular UART interfaces. Now UART interfaces are configured in a standard, extensible way.

Related to #18836. Needed to unblock progress on the RPi4B PL011 UART interfaces for GSoC 2026.

Impact

Impacts only the 4 (simulator) boards that used PL011 UART.

Testing

For each of the QEMU boards, I tested their gdbstub demos since those configurations use both UART interfaces, not just a console.

QEMU ARMv8A

Details
$ qemu-system-aarch64 -cpu cortex-a53 -nographic -machine virt,virtualization=on,gic-version=3 -net none -kernel ./nuttx -serial mon:stdio -serial pty
char device redirected to /dev/pts/1 (label serial1)
- Ready to Boot Primary CPU
- Boot from EL2
- Boot from EL1
- Boot to C runtime for OS Initialize

NuttShell (NSH) NuttX-12.13.0
nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    0     0     0   0 FIFO     Kthread   - Ready              0000000000000000 0008144 0001664  20.4%  Idle_Task
    1     0     0 192 RR       Kthread   - Waiting  Semaphore 0000000000000000 0008080 0001152  14.2%  hpwork 0x403cf6d0 0x403cf758
    3     3     0 100 RR       Task      - Running            0000000000000000 0008112 0003840  47.3%  nsh_main
nsh> ls
/:
 dev/
 proc/
 tmp/
$ gdb nuttx -ex "target remote /dev/pts/1"
GNU gdb (GDB) 17.1
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from nuttx...
Remote debugging using /dev/pts/1
0x0000000040297528 in up_idle () at common/arm64_idle.c:65
65      }
(gdb) exit

QEMU ARMv7A

Details
$ qemu-system-arm -cpu cortex-a7 -nographic -machine virt,virtualization=off,gic-version=2 -net none -kernel ./nuttx  -serial mon:stdio -serial pty
char device redirected to /dev/pts/2 (label serial1)
nx_start: Entry
uart_register: Registering /dev/console
uart_register: Registering /dev/ttyS0
work_start_highpri: Starting high-priority kernel worker thread(s)
nxtask_activate: hpwork pid=1,TCB=0x4020d5c0
nxtask_activate: AppBringUp pid=2,TCB=0x4020e690
nx_start_application: Starting init thread
task_spawn: name=nsh_main entry=0x60ccac file_actions=0 attr=0x4020f724 argv=0x4020f720
nxtask_activate: nsh_main pid=3,TCB=0x4020f790
nxtask_exit: AppBringUp pid=2,TCB=0x4020e690
lib_cxx_initialize: _sinit: 0x631110 _einit: 0x631110

NuttShell (NSH) NuttX-12.13.0
nsh> nx_start: CPU0: Beginning Idle Loop

nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    0     0     0   0 FIFO     Kthread   - Ready              0000000000000000 0004072 0000704  17.2%  Idle_Task
    1     0     0 192 RR       Kthread   - Waiting  Semaphore 0000000000000000 0004024 0000456  11.3%  hpwork 0x40200150 0x40200198
    3     3     0 100 RR       Task      - Running            0000000000000000 0004048 0001552  38.3%  nsh_main
nsh>
$ gdb nuttx -ex "target remote /dev/pts/2"
GNU gdb (GDB) 17.1
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from nuttx...
Remote debugging using /dev/pts/2
0x0060c488 in up_idle () at chip/qemu_idle.c:63
63      }
(gdb) exit

For the FVP boards, I tested compilation only.

The CXD32 and and Goldfish chips don't have any defconfigs to test.

@github-actions github-actions Bot added Arch: arm Issues related to ARM (32-bit) architecture Arch: arm64 Issues related to ARM64 (64-bit) architecture Area: Drivers Drivers issues Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. Board: arm Board: arm64 labels May 2, 2026
@linguini1 linguini1 requested review from cederom and michallenc May 2, 2026 19:53
@linguini1
Copy link
Copy Markdown
Contributor Author

linguini1 commented May 2, 2026

I am able to run the qemu-armv8a:citest binary locally with the same invocation used by NTFC:

$ qemu-system-aarch64 -cpu cortex-a53 -nographic -machine virt,virtualization=on,gic-version=3 -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel ./nuttx

NuttShell (NSH) NuttX-12.13.0
nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    0     0     0   0 FIFO     Kthread   - Ready              0000000000000000 0008144 0001616  19.8%  Idle_Task
    1     0     0 192 RR       Kthread   - Waiting  Semaphore 0000000000000000 0008080 0001200  14.8%  hpwork 0x404196a0 0x40419728
    3     3     0 100 RR       Task      - Running            0000000000000000 0008112 0003728  45.9%  nsh_main
nsh> ls
/:
 dev/
 proc/
 tmp/
nsh>

It's also odd that it works for SMP.

@linguini1
Copy link
Copy Markdown
Contributor Author

@raiden00pl Do you have any idea why this change might cause NTFC to fail with a boot timeout on qemu-armv8a:citest but not qemu-armv8a:citest_smp?

@raiden00pl
Copy link
Copy Markdown
Member

no idea. NTFC should export nuttx.elf in CI artifacts, but for some reason these are not present for qemu-armv8a:citest and qemu-armv8a:citest_smp. What's funny - it works for all other targets citest targets.

Now I see that this target uses cmake, so that might be the reason for the missing elf in the artifacts.

@xiaoxiang781216 xiaoxiang781216 linked an issue May 3, 2026 that may be closed by this pull request
1 task
*
***************************************************************************/

void pl011_serialinit(void)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why drop the default implementation which could avoid the code duplication in the common case. it's better that:

  1. keep pl011_serialinit/pl011_earlyserialinit if one of CONFIG_UARTx_PL011 is enabled
  2. add pl011_dev_init, so the special case could call the new function directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this function is no longer useful. It needs access to the device structs for the PL011 interfaces in order to register them, but these are defined outside this module now.

If we keep this function, then we can no longer:

  • Define an arbitrary number of interfaces
  • Use the standard UART config options for configuring PL011 UART

It should now be up to the chip logic to register the UART interfaces instead, as with all other UART drivers. Otherwise we don't have the benefits and we must also maintain two separate ways of doing things. There are only 3 boards that use PL011 right now, so it's not a super common case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the similar config duplicated in the many places now. I would prefer to keep the origin global definition, so the common usage could be simplified.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure there's a way around that except by maintaining two interfaces for PL011 registration and all the old Kconfig options. Plus, I will have to add some refactoring for more granular interrupt management.

Let me brainstorm and get back to you, maybe I can keep the init function and still remove the PL011-specific Kconfig functions. The main challenge is selection of the base addresses and IRQ numbers.

@linguini1
Copy link
Copy Markdown
Contributor Author

Now I see that this target uses cmake, so that might be the reason for the missing elf in the artifacts.

I'll try building with CMake in case that reveals what the issue might be.

This commit refactors the PL011 UART driver so that it can be re-used
for any number of UART interfaces depending on the board/chip. This
commit also hooks the UART interface configuration/selection for PL011
UART interfaces into the same Kconfig used for regular UART interfaces.
Now UART interfaces are configured in a standard, extensible way.

Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
@linguini1
Copy link
Copy Markdown
Contributor Author

linguini1 commented May 25, 2026

Okay so I built qemu-armv8a:citest locally using CMake:

$ cmake -B build -DBOARD_CONFIG=qemu-armv8a:citest -GNinja
$ cmake --build build

Then I downloaded the nuttx-ntfc and nuttx-ntfc-testing repositories to run the CI test-suites locally:

$ ntfc test --testpath=/home/linguini/coding/nuttx-space/nuttx-ntfc/external/nuttx-testing/ --confpath=/home/linguini/coding/nuttx-space/nuttx/boards/arm64/qemu/qemu-armv8a/configs/citest/config.yaml --jsonconf=/home/linguini/coding/nuttx-space/nuttx/boards/arm64/qemu/qemu-armv8a/configs/citest/session.json
--------------------------------------------------------------------------------
NTFC PID: 3606981
--------------------------------------------------------------------------------
YAML config:
{'config': {'cwd': './', 'kv': [], 'loops': 1},
 'product': {'cores': {'core0': {'conf_path': './build/.config',
                                 'device': 'qemu',
                                 'elf_path': './build/nuttx',
                                 'exec_args': '-cpu cortex-a53 -nographic '
                                              '-machine '
                                              'virt,virtualization=on,gic-version=3 '
                                              '-net none -chardev '
                                              'stdio,id=con,mux=on -serial '
                                              'chardev:con -mon '
                                              'chardev=con,mode=readline',
                                 'exec_path': 'qemu-system-aarch64',
                                 'name': 'main'}},
             'name': 'qemu-armv8a'}}
JSON config:
{'args': {'kv': []},
 'module': {'exclude_module': ['Nuttx_System_Fs_Fs'],
            'include_module': [],
            'order': []}}
CPU information header not found in output
==================================================================== test session starts =====================================================================
platform linux -- Python 3.14.5, pytest-9.0.3, pluggy-1.6.0
rootdir: /home/linguini/coding/nuttx-space/nuttx-ntfc
configfile: tox.ini
plugins: html-4.2.0, repeat-0.9.4, ordering-0.6, dependency-0.6.1, metadata-3.1.1, timeout-2.4.0
collected 932 items                                                                                                                                          

=================================================================== no tests ran in 0.38s ====================================================================

====================================================================================================
  🚀 RUNNING 63 SELECTED TEST(S)
====================================================================================================
┼─────┼──────────────────────────────────┼──────────────────────────────┼
│ Idx │ Module                           │ Test Case                    │
┼─────┼──────────────────────────────────┼──────────────────────────────┼
│   1 │ Nuttx_System_Arch_Os_Integration │ test_os[main]                │
│   2 │ Nuttx_System_Arch_Example        │ test_hello_integration[main] │
│   3 │ Nuttx_System_Arch_Example        │ test_getprime                │
│   4 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat001[main]    │
│   5 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat002[main]    │
│   6 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat003[main]    │
│   7 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat004[main]    │
│   8 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat005[main]    │
│   9 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat006[main]    │
│  10 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat007[main]    │
│  11 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat008[main]    │
│  12 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat009[main]    │
│  13 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat010[main]    │
│  14 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd001            │
│  15 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd002            │
│  16 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd003            │
│  17 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd004            │
│  18 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd005            │
│  19 │ Nuttx_System_Arch_Nsh            │ TestEcho.test_echo001        │
│  20 │ Nuttx_System_Arch_Nsh            │ TestEcho.test_echo002        │
│  21 │ Nuttx_System_Arch_Nsh            │ TestEcho.test_echo003        │
│  22 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help01         │
│  23 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help02         │
│  24 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help_v         │
│  25 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help_cat       │
│  26 │ Nuttx_System_Arch_Nsh            │ TestLs.test_ls_l             │
│  27 │ Nuttx_System_Arch_Nsh            │ TestLs.test_ls_s             │
│  28 │ Nuttx_System_Arch_Nsh            │ TestLs.test_ls_R             │
│  29 │ Nuttx_System_Arch_Nsh            │ TestRm.test_rm001            │
│  30 │ Nuttx_System_Arch_Nsh            │ TestRm.test_rm002            │
│  31 │ Nuttx_System_Arch_Nsh            │ TestMkdir.test_mkdir001      │
│  32 │ Nuttx_System_Arch_Nsh            │ TestRmdir.test_rmdir001      │
│  33 │ Nuttx_System_Arch_Nsh            │ TestRmdir.test_rmdir002      │
│  34 │ Nuttx_System_Arch_Nsh            │ TestCp.test_cp001            │
│  35 │ Nuttx_System_Arch_Nsh            │ TestCp.test_cp002            │
│  36 │ Nuttx_System_Arch_Nsh            │ TestCp.test_cp003            │
│  37 │ Nuttx_System_Arch_Nsh            │ TestPs.test_ps               │
│  38 │ Nuttx_System_Arch_Nsh            │ TestTime.test_sleep          │
│  39 │ Nuttx_System_Arch_Nsh            │ TestTime.test_usleep         │
│  40 │ Nuttx_System_Arch_Nsh            │ TestSet.test_set             │
│  41 │ Nuttx_System_Arch_Nsh            │ TestSet.test_unset           │
│  42 │ Nuttx_System_Arch_Nsh            │ TestTest.test_test           │
│  43 │ Nuttx_System_Arch_Nsh            │ TestDirname.test_dirname     │
│  44 │ Nuttx_System_Arch_Nsh            │ TestBasename.test_basename   │
│  45 │ Nuttx_System_Arch_Nsh            │ TestDf.test_df               │
│  46 │ Nuttx_System_Arch_Nsh            │ TestDf.test_df_h             │
│  47 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname         │
│  48 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_a       │
│  49 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_s       │
│  50 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_r       │
│  51 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_v       │
│  52 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_m       │
│  53 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_i       │
│  54 │ Nuttx_System_Arch_Nsh            │ TestEnv.test_env             │
│  55 │ Nuttx_System_Arch_Nsh            │ TestMv.test_mv               │
│  56 │ Nuttx_System_Arch_Nsh            │ TestPwd.test_pwd             │
│  57 │ Nuttx_System_Arch_Nsh            │ TestHexdump.test_hexdump     │
│  58 │ Nuttx_System_Arch_Nsh            │ TestMkrd.test_mkrd           │
│  59 │ Nuttx_System_Arch_Nsh            │ TestMw.test_mw               │
│  60 │ Nuttx_System_Arch_Nsh            │ TestExec.test_exec           │
│  61 │ Nuttx_System_Arch_Space          │ test_free[main]              │
│  62 │ Nuttx_System_Arch_Space          │ test_df[main]                │
│  63 │ Nuttx_System_Tools               │ test_system_mmleak           │
┼─────┼──────────────────────────────────┼──────────────────────────────┼
====================================================================================================

CPU information header not found in output
==================================================================== test session starts =====================================================================
platform linux -- Python 3.14.5, pytest-9.0.3, pluggy-1.6.0
rootdir: /home/linguini/coding/nuttx-space/nuttx-ntfc
configfile: tox.ini
plugins: html-4.2.0, repeat-0.9.4, ordering-0.6, dependency-0.6.1, metadata-3.1.1, timeout-2.4.0
timeout: 800.0s
timeout method: signal
timeout func_only: False
session timeout: 3600.0s
collected 64 items                                                                                                                                           

../nuttx-ntfc/external/nuttx-testing/arch/os/integration/test_arch_os_integration.py::test_os[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/example/test_arch_example_integration.py::test_hello_integration[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/example/test_arch_example_integration.py::test_getprime PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat001[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat002[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat003[main] 

It works fine. I even made sure to use release-0.0.1. However, running the CI through the manual CI testing repository, I can see it fail again for this specific configuration: https://github.com/linguini1/manual-nuttx-ci/actions/runs/26415001939/job/77757543595

I'm genuinely at a loss for what's going on. Can you spot anything @raiden00pl?

@linguini1 linguini1 requested a review from raiden00pl May 25, 2026 19:49
@raiden00pl
Copy link
Copy Markdown
Member

Did you run this on your host or from nuttx-ci docker? I also checked it on my host, and this change pass ntfc tests. So I think there might be something wrong with image produced by docker itself, or maybe qemu version that is installed on this image

@linguini1
Copy link
Copy Markdown
Contributor Author

Did you run this on your host or from nuttx-ci docker? I also checked it on my host, and this change pass ntfc tests. So I think there might be something wrong with image produced by docker itself, or maybe qemu version that is installed on this image

This was run on my host, not from the nuttx-ci docker. Darn, what a pesky bug to track down!

@linguini1
Copy link
Copy Markdown
Contributor Author

Okay it looks the CI uses QEMU version 6.2.0, while I have 11.0.0 (for aarch64). Not sure if this is necessarily the culprit but I'll investigate.

@linguini1
Copy link
Copy Markdown
Contributor Author

linguini1 commented May 25, 2026

Even more hair pulling. I downloaded the latest CI docker image and ran it

$ docker pull ghcr.io/apache/nuttx/apache-nuttx-ci-linux:latest

Then I cloned my branch with these changes, nuttx-apps, nuttx-ntfc, nuttx-ntfc-testing, installed NTFC, built qemu-armv8a:citest with CMake, etc. inside the Docker container. And...... it works fine:

$ ntfc test --testpath=../nuttx-ntfc/external/nuttx-testing/ --confpath=boards/arm64/qemu/qemu-armv8a/configs/citest/config.yaml --jsonconf=boards/arm64/qemu/qemu-armv8a/configs/citest/session.json
--------------------------------------------------------------------------------
NTFC PID: 11313
--------------------------------------------------------------------------------
YAML config:
{'config': {'cwd': './', 'kv': [], 'loops': 1},
 'product': {'cores': {'core0': {'conf_path': './build/.config',
                                 'device': 'qemu',
                                 'elf_path': './build/nuttx',
                                 'exec_args': '-cpu cortex-a53 -nographic '
                                              '-machine '
                                              'virt,virtualization=on,gic-version=3 '
                                              '-net none -chardev '
                                              'stdio,id=con,mux=on -serial '
                                              'chardev:con -mon '
                                              'chardev=con,mode=readline',
                                 'exec_path': 'qemu-system-aarch64',
                                 'name': 'main'}},
             'name': 'qemu-armv8a'}}
JSON config:
{'args': {'kv': []},
 'module': {'exclude_module': ['Nuttx_System_Fs_Fs'],
            'include_module': [],
            'order': []}}
CPU information header not found in output
================================================================== test session starts ===================================================================
platform linux -- Python 3.10.12, pytest-9.0.3, pluggy-1.6.0
rootdir: /tools/nuttx-space/nuttx-ntfc
configfile: tox.ini
plugins: html-4.2.0, dependency-0.6.1, metadata-3.1.1, timeout-2.4.0, repeat-0.9.1, ordering-0.6, json-0.4.0
collected 932 items                                                                                                                                      

================================================================= no tests ran in 0.41s ==================================================================

====================================================================================================
  🚀 RUNNING 63 SELECTED TEST(S)
====================================================================================================
┼─────┼──────────────────────────────────┼──────────────────────────────┼
│ Idx │ Module                           │ Test Case                    │
┼─────┼──────────────────────────────────┼──────────────────────────────┼
│   1 │ Nuttx_System_Arch_Os_Integration │ test_os[main]                │
│   2 │ Nuttx_System_Arch_Example        │ test_hello_integration[main] │
│   3 │ Nuttx_System_Arch_Example        │ test_getprime                │
│   4 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat001[main]    │
│   5 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat002[main]    │
│   6 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat003[main]    │
│   7 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat004[main]    │
│   8 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat005[main]    │
│   9 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat006[main]    │
│  10 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat007[main]    │
│  11 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat008[main]    │
│  12 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat009[main]    │
│  13 │ Nuttx_System_Arch_Nsh            │ TestCat.test_cat010[main]    │
│  14 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd001            │
│  15 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd002            │
│  16 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd003            │
│  17 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd004            │
│  18 │ Nuttx_System_Arch_Nsh            │ TestCd.test_cd005            │
│  19 │ Nuttx_System_Arch_Nsh            │ TestEcho.test_echo001        │
│  20 │ Nuttx_System_Arch_Nsh            │ TestEcho.test_echo002        │
│  21 │ Nuttx_System_Arch_Nsh            │ TestEcho.test_echo003        │
│  22 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help01         │
│  23 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help02         │
│  24 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help_v         │
│  25 │ Nuttx_System_Arch_Nsh            │ TestHelp.test_help_cat       │
│  26 │ Nuttx_System_Arch_Nsh            │ TestLs.test_ls_l             │
│  27 │ Nuttx_System_Arch_Nsh            │ TestLs.test_ls_s             │
│  28 │ Nuttx_System_Arch_Nsh            │ TestLs.test_ls_R             │
│  29 │ Nuttx_System_Arch_Nsh            │ TestRm.test_rm001            │
│  30 │ Nuttx_System_Arch_Nsh            │ TestRm.test_rm002            │
│  31 │ Nuttx_System_Arch_Nsh            │ TestMkdir.test_mkdir001      │
│  32 │ Nuttx_System_Arch_Nsh            │ TestRmdir.test_rmdir001      │
│  33 │ Nuttx_System_Arch_Nsh            │ TestRmdir.test_rmdir002      │
│  34 │ Nuttx_System_Arch_Nsh            │ TestCp.test_cp001            │
│  35 │ Nuttx_System_Arch_Nsh            │ TestCp.test_cp002            │
│  36 │ Nuttx_System_Arch_Nsh            │ TestCp.test_cp003            │
│  37 │ Nuttx_System_Arch_Nsh            │ TestPs.test_ps               │
│  38 │ Nuttx_System_Arch_Nsh            │ TestTime.test_sleep          │
│  39 │ Nuttx_System_Arch_Nsh            │ TestTime.test_usleep         │
│  40 │ Nuttx_System_Arch_Nsh            │ TestSet.test_set             │
│  41 │ Nuttx_System_Arch_Nsh            │ TestSet.test_unset           │
│  42 │ Nuttx_System_Arch_Nsh            │ TestTest.test_test           │
│  43 │ Nuttx_System_Arch_Nsh            │ TestDirname.test_dirname     │
│  44 │ Nuttx_System_Arch_Nsh            │ TestBasename.test_basename   │
│  45 │ Nuttx_System_Arch_Nsh            │ TestDf.test_df               │
│  46 │ Nuttx_System_Arch_Nsh            │ TestDf.test_df_h             │
│  47 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname         │
│  48 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_a       │
│  49 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_s       │
│  50 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_r       │
│  51 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_v       │
│  52 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_m       │
│  53 │ Nuttx_System_Arch_Nsh            │ TestUname.test_uname_i       │
│  54 │ Nuttx_System_Arch_Nsh            │ TestEnv.test_env             │
│  55 │ Nuttx_System_Arch_Nsh            │ TestMv.test_mv               │
│  56 │ Nuttx_System_Arch_Nsh            │ TestPwd.test_pwd             │
│  57 │ Nuttx_System_Arch_Nsh            │ TestHexdump.test_hexdump     │
│  58 │ Nuttx_System_Arch_Nsh            │ TestMkrd.test_mkrd           │
│  59 │ Nuttx_System_Arch_Nsh            │ TestMw.test_mw               │
│  60 │ Nuttx_System_Arch_Nsh            │ TestExec.test_exec           │
│  61 │ Nuttx_System_Arch_Space          │ test_free[main]              │
│  62 │ Nuttx_System_Arch_Space          │ test_df[main]                │
│  63 │ Nuttx_System_Tools               │ test_system_mmleak           │
┼─────┼──────────────────────────────────┼──────────────────────────────┼
====================================================================================================

CPU information header not found in output
================================================================== test session starts ===================================================================
platform linux -- Python 3.10.12, pytest-9.0.3, pluggy-1.6.0
rootdir: /tools/nuttx-space/nuttx-ntfc
configfile: tox.ini
plugins: html-4.2.0, dependency-0.6.1, metadata-3.1.1, timeout-2.4.0, repeat-0.9.1, ordering-0.6, json-0.4.0
timeout: 800.0s
timeout method: signal
timeout func_only: False
session timeout: 3600.0s
collected 64 items                                                                                                                                       

../nuttx-ntfc/external/nuttx-testing/arch/os/integration/test_arch_os_integration.py::test_os[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/example/test_arch_example_integration.py::test_hello_integration[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/example/test_arch_example_integration.py::test_getprime PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat001[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat002[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat003[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat004[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat005[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat006[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat007[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat008[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat009[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat010[main] PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCd::test_cd001 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCd::test_cd002 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCd::test_cd003 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCd::test_cd004 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestCd::test_cd005 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestEcho::test_echo001 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestEcho::test_echo002 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestEcho::test_echo003 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestHelp::test_help01 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestHelp::test_help02 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestHelp::test_help_v PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestHelp::test_help_cat PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestLs::test_ls_l PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestLs::test_ls_s SKIPPED (No Ready)
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestLs::test_ls_R PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestRm::test_rm001 PASSED
../nuttx-ntfc/external/nuttx-testing/arch/nsh/test_arch_nsh_integration.py::TestRm::test_rm002 PASSED

@simbit18 or @lupyuen , do you have any idea what might be going on here? Any advice for getting closer to reproducing the CI conditions locally?

@lupyuen
Copy link
Copy Markdown
Member

lupyuen commented May 26, 2026

@linguini1 Following these Docker Steps: I'm hitting some errors with cibuild.sh at qemu-armv8a:citest_smp. Are you able to reproduce this? https://gist.github.com/lupyuen/42df35f7c96ef79f3402353c0065af5c

## Based on https://lupyuen.org/articles/ci2#build-nuttx-for-one-target-group
## Tested on Ubuntu 24.04.2 LTS x86_64
$ sudo docker run \
  -it \
  ghcr.io/apache/nuttx/apache-nuttx-ci-linux:latest \
  /bin/bash
$ pip install ntfc
$ mkdir $HOME/nuttx-ntfc
$ mkdir $HOME/nuttx-ntfc/external
$ cd $HOME/nuttx-ntfc/external
$ git clone -b release-0.0.1 https://github.com/apache/nuttx-ntfc-testing
$ mv nuttx-ntfc-testing nuttx-testing
$ export NTFCDIR=$HOME/nuttx-ntfc
$ cd
$ git clone https://github.com/linguini1/nuttx --branch pl011-uart
HEAD is now at 0fd76d2a1c drivers/serial: Refactor PL011 to be general-purpose
NuttX Source: https://github.com/apache/nuttx/tree/0fd76d2a1c9a6f281138b4df2ba8dda736e72575
$ git clone https://github.com/apache/nuttx-apps apps
HEAD is now at 939ed0ca2 apps/system/microros: add rcutils strcasecmp strings.h include patch.
NuttX Apps: https://github.com/apache/nuttx-apps/tree/939ed0ca2a7b593949973be5d09aefea1b659418
$ cd ~/nuttx/tools/ci
$ ./cibuild.sh -c -A -N -R testlist/arm64-01.dat
Configuration/Tool: qemu-armv8a/citest_smp
.../arch/os/integration/test_arch_os_integration.py::test_os[main] PASSED
.../arch/example/test_arch_example_integration.py::test_hello_integration[main] PASSED
.../arch/example/test_arch_example_integration.py::test_getprime PASSED
.../arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat001[main] FAILED
.../arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat002[main] FAILED
.../arch/nsh/test_arch_nsh_integration.py::TestCat::test_cat003[main] FAILED

Update: cibuild.sh on Master Branch is strangely inconsistent. Is QEMU or NTFC preserving some state? Hmmm https://gist.github.com/lupyuen/f11430c9d6ebfdf6e9d9c7b4d14fd2e2

$ git clone https://github.com/apache/nuttx
$ git clone https://github.com/apache/nuttx-apps apps
$ cd ~/nuttx/tools/ci
$ ./cibuild.sh -c -A -N -R testlist/arm64-01.dat
Build Attempt 1 of 4
Configuration/Tool: qemu-armv8a/citest_smp
../nuttx-ntfc/external/nuttx-testing/arch/os/integration/test_arch_os_integration.py::test_os[main] FAILED
...
Build Attempt 2 of 4
Configuration/Tool: qemu-armv8a/citest_smp
[ No Failures ]

@lupyuen
Copy link
Copy Markdown
Member

lupyuen commented May 26, 2026

@linguini1 You might wanna check these Build Errors:

(1) https://github.com/lupyuen260526/nuttx/actions/runs/26436834321/job/77821696938#step:10:898

Configuration/Tool: fvp-armv8r-aarch32/nsh,CONFIG_ARM_TOOLCHAIN_GNU_EABI
  [1/1] Normalize fvp-armv8r-aarch32/nsh
27,29d26
< CONFIG_FVP_ARMV8R_UART0=y
< CONFIG_FVP_ARMV8R_UART2=y
< CONFIG_FVP_ARMV8R_UART3=y
32a30,32
> CONFIG_FVP_ARMV8R_UART0=y
> CONFIG_FVP_ARMV8R_UART2=y
> CONFIG_FVP_ARMV8R_UART3=y

(2) https://github.com/lupyuen260526/nuttx/actions/runs/26436834321/job/77821696977#step:10:1704

Configuration/Tool: qemu-armv7r/pnsh,CONFIG_ARM_TOOLCHAIN_GNU_EABI
arm-none-eabi-ld: /github/workspace/sources/nuttx/staging/libdrivers.a(syslog_channel.o): in function `syslog_default_putc':
/github/workspace/sources/nuttx/drivers/syslog/syslog_channel.c:295:(.text.syslog_default_putc+0x30): undefined reference to `up_putc'
arm-none-eabi-ld: /github/workspace/sources/nuttx/drivers/syslog/syslog_channel.c:300:(.text.syslog_default_putc+0x44): undefined reference to `up_putc'
arm-none-eabi-ld: /github/workspace/sources/nuttx/staging/libkarch.a(arm_nputs.o): in function `up_nputs':
/github/workspace/sources/nuttx/arch/arm/src/common/arm_nputs.c:47:(.text.up_nputs+0x20): undefined reference to `up_putc'
  [1/1] Normalize qemu-armv7r/pnsh
57,61d56
< CONFIG_UART1_BASE=0x9000000
< CONFIG_UART1_IRQ=33
< CONFIG_UART1_PL011=y
< CONFIG_UART1_SERIAL_CONSOLE=y
< CONFIG_UART_PL011=y

@raiden00pl
Copy link
Copy Markdown
Member

@linguini1 I ran docker CI for this PR on my host and all tests pass... I have no idea where the problem could be.

Next thing I would try is to export nuttx elf which is built on github CI, I would download CI artifacts with it and see if it works locally on the host.
You could change the build for failing citest config from cmake to make and see if it works. If it doesn't, at least you'll be able to easily download the nuttx elf that doesn't work and run it locally.

@cederom
Copy link
Copy Markdown
Contributor

cederom commented May 26, 2026

Will take a look today, thank you @linguini1 :-)

Looking at the @xiaoxiang781216 comment, maybe it is possible to add parameter to existing functions to tell which port we want to use to be least invasive?

If current approach is blocking, on the other hand, it may need an update. Will take a look into details in few hours, sorry for the delay :-)

@cederom
Copy link
Copy Markdown
Contributor

cederom commented May 26, 2026

@linguini1 I ran docker CI for this PR on my host and all tests pass... I have no idea where the problem could be.

Next thing I would try is to export nuttx elf which is built on github CI, I would download CI artifacts with it and see if it works locally on the host. You could change the build for failing citest config from cmake to make and see if it works. If it doesn't, at least you'll be able to easily download the nuttx elf that doesn't work and run it locally.

Maybe we could create SBOM for the CI Docker image so we know what are exact dependencies? :-)

@linguini1
Copy link
Copy Markdown
Contributor Author

@lupyuen thanks for the testing help! I did not try running with the cibuild script, I only targeted the failing qemu-armv8a:citest build. I can try it that way instead. I've fixed the two errors you found though; I'm keeping all those changes on a branch called pl011-uart-test so I avoid re-triggering the CI build here every time I upstream.

I will try raiden's suggestion of building in CI with Make instead of CMake so I can download the artifact. Hopefully that reveals something!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Arch: arm64 Issues related to ARM64 (64-bit) architecture Area: Drivers Drivers issues Board: arm Board: arm64 Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Re-usable PL011 UART driver

5 participants